package com.mhxy.controller;

import cn.hutool.core.util.StrUtil;
import com.mhxy.constant.TaskConstants;
import com.mhxy.entity.TableData;
import com.mhxy.handler.ConfigHandler;
import com.mhxy.handler.TaskProgressHandler;
import com.mhxy.util.AppUtil;
import com.mhxy.util.HwndUtil;
import com.mhxy.util.DirUtil;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.*;
import com.mhxy.enums.CheckBoxType;
import javafx.beans.property.BooleanProperty;

@Slf4j
public class AppController {

    /**
     * 选择的任务列表 - 改用Set避免重复
     */
    private static final Set<String> TASK_SET = new LinkedHashSet<>();

    /**
     * TableView的部分组件
     */
    @FXML
    private TableView<TableData> tableView;
    @FXML
    private TableColumn<TableData, String> actionCol;
    private final ObservableList<TableData> tableDataList = FXCollections.observableArrayList();

    @FXML
    private ComboBox<String> loginInfoBox;

    /**
     * 所有CheckBox的映射
     */
    private final Map<String, CheckBox> checkBoxMap = new HashMap<>();

    @FXML
    private CheckBox singleC1, singleC2, singleC4, singleC5, singleC6, singleC7,
                    singleC8, singleC9, singleC10, singleC11, singleC12, singleC13,
                    singleC14, singleC15, singleC16, singleC17;
    @FXML
    private CheckBox multiC1, multiC2, multiC3, multiC4, multiC5, multiC6, multiC7, multiC8, multiC9,
            multiC10, multiC11, multiC12, multiC13, multiC14;
    @FXML
    private CheckBox otherC1, otherC2, otherC3, otherC4, otherC5, otherC6, otherC7, otherC8;

    /**
     * 默认的初始化方法
     */
    @FXML
    private void initialize() {
        try {
            // 加载配置文件
            ConfigHandler.loadConfig();
            ConfigHandler.loadOpenCV();
            DirUtil.initTempPicPath();
            
            // 初始化组件
            initCheckBoxes();
            initTableView();
            initLoginBox();
        } catch (Exception e) {
            log.error("初始化失败", e);
            // 可以在这里添加错误提示对话框
        }
    }

    private void initLoginBox() {
        // 设置默认选项
        loginInfoBox.getSelectionModel().selectFirst();
        // 监听 ComboBox 的选择事件
        loginInfoBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
//            ConfigHandler.switchGameLoginInfo(newValue);
        });
    }

    private void initTableView() {
        refreshAllData();

        // 设置 Action 列（包含两个按钮）
        actionCol.setCellFactory(column -> new TableCell<TableData, String>() {
            private final Button button1 = new Button("启动");
            private final Button button2 = new Button("清空");

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setGraphic(null);
                } else {
                    // 设置按钮布局
                    HBox hbox = new HBox(5, button1, button2);
                    setGraphic(hbox);

                    // 绑定按钮事件
                    TableData userInfo= getTableView().getItems().get(getIndex());
                    button1.setOnAction(event -> handleStart(event, userInfo));
                    button2.setOnAction(event -> handleClear(event, userInfo));
                }
            }
        });

        // 将数据绑定到表格
        tableView.setItems(tableDataList);
        // 定时刷新数据
        Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(5), event -> refreshAllData()));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    /**
     * 启动
     */
    private void handleStart(ActionEvent event, TableData userInfo) {
        if (TASK_SET.isEmpty()) {
            AppUtil.alter(event, "提示", null, "你还未选择任何任务！");
            return;
        }
        String tasks = String.join("\n", TASK_SET);
        boolean result = AppUtil.confirm(event, "选择线程" + userInfo.getHwndName(), "你选择了以下任务，确定执行吗？", tasks.isEmpty() ? "没有选中任何任务" : tasks);
        if (!result) {
            return;
        }

        try {
            StartController.run(userInfo.getHwndName(), new ArrayList<>(TASK_SET));
        } catch (Exception e) {
            log.error("启动任务失败", e);
            AppUtil.alter(event, "错误", null, "启动失败：" + e.getMessage());
        }
    }

    /**
     * 全部启动
     */
    @FXML
    private void handlerStartAll(MouseEvent event) {
        if (TASK_SET.isEmpty()) {
            AppUtil.alter(event, "提示", null, "你还未选择任何任务！");
            return;
        }

        String taskMsg = String.join("\n", TASK_SET);
        boolean result = AppUtil.confirm(event, "全部线程", "你选择了以下任务，确定执行吗？", taskMsg.isEmpty() ? "没有选中任何任务" : taskMsg);
        if (!result) {
            return;
        }

        try {
            List<String> tasks = new ArrayList<>(TASK_SET);
            HwndUtil.hwndsMap.keySet().forEach(k -> StartController.run(k, tasks));
            refreshAllData();
            AppUtil.alter(event, "启动任务", null, "启动成功！");
        } catch (Exception e) {
            log.error("批量启动任务失败", e);
            AppUtil.alter(event, "错误", null, "启动失败：" + e.getMessage());
        }
    }

    /**
     * 清空任务
     */
    private void handleClear(ActionEvent event, TableData tableData) {
        TaskProgressHandler.clearTasks(tableData.getHwndName());
        refreshData(tableData);
    }

    /**
     * 全部清空
     */
    @FXML
    private void handlerClearAll(MouseEvent event) {
        HwndUtil.hwndsMap.keySet().forEach(TaskProgressHandler::clearTasks);
        refreshAllData();
    }

    /**
     * 打开游戏窗口
     */
    @FXML
    private void handleOpenPcButton(MouseEvent event) throws Exception {
        boolean isConfirmed  = AppUtil.confirm(event, "打开游戏窗口", "您确认这几个游戏窗口吗？", ConfigHandler.getBoxNames().toString());
        if (!isConfirmed) {
            return;
        }
        OpenController.run(false);
        AppUtil.alter(event, "启动任务", null, "启动成功！");
    }

    /**
     * 打开游戏窗口+登录游戏
     */
    @FXML
    private void handleOpenAndLoginButton(MouseEvent event) throws Exception {
        boolean isConfirmed  = AppUtil.confirm(event, "登录游戏", "您确认登录这一组账号吗？", loginInfoBox.getValue());
        if (!isConfirmed) {
            return;
        }
        OpenController.run(true);
    }

    /**
     * 登录游戏
     */
    @FXML
    private void handleLoginButton(MouseEvent event) throws Exception {
        boolean isConfirmed  = AppUtil.confirm(event, "登录游戏", "您确认登录这一组账号吗？", loginInfoBox.getValue());
        if (!isConfirmed) {
            return;
        }

        ConfigHandler.switchGameLoginInfo(loginInfoBox.getValue());

        List<String> tasks = Collections.singletonList(TaskConstants.LOGIN_GAME);
        HwndUtil.hwndsMap.keySet().forEach(k -> {
            StartController.run(k, tasks);
        });
    }

    /**
     * 切换登录账号
     */
    @FXML
    private void handleSwitchAccountButton(MouseEvent event) throws Exception {
        boolean isConfirmed  = AppUtil.confirm(event, "切换登录账号", "您确认切换登录这一组账号吗？", loginInfoBox.getValue());
        if (!isConfirmed) {
            return;
        }

        ConfigHandler.switchGameLoginInfo(loginInfoBox.getValue());

        List<String> tasks = Collections.singletonList(TaskConstants.SWITCH_ACCOUNT);
        HwndUtil.hwndsMap.keySet().forEach(k -> {
            StartController.run(k, tasks);
        });
    }

    /**
     * 初始化所有CheckBox
     */
    private void initCheckBoxes() {
        // 初始化checkBoxMap
        for (CheckBoxType type : CheckBoxType.values()) {
            CheckBox checkBox = (CheckBox) getFieldValue(type.getCheckBoxId());
            if (checkBox != null) {
                checkBoxMap.put(type.getCheckBoxId(), checkBox);
                bindCheckBoxListener(checkBox, type);
            }
        }
    }

    /**
     * 绑定CheckBox监听器
     */
    private void bindCheckBoxListener(CheckBox checkBox, CheckBoxType type) {
        BooleanProperty selectedProperty = checkBox.selectedProperty();
        selectedProperty.addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                TASK_SET.add(type.getTaskName());
            } else {
                TASK_SET.remove(type.getTaskName());
            }
            log.debug("任务列表更新: {}", TASK_SET);
        });
    }

    /**
     * 通过反射获取字段值
     */
    private Object getFieldValue(String fieldName) {
        try {
            Field field = this.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(this);
        } catch (Exception e) {
            log.error("获取字段值失败: {}", fieldName, e);
            return null;
        }
    }

    @FXML
    private void refreshAllData() {
        tableDataList.clear();
        Map<String, HwndUtil.HwndEntity> hwndMap = HwndUtil.getStartHwnds();
        hwndMap.keySet().forEach(k -> {
            String taskProgress = TaskProgressHandler.getTaskProgress(k);
            String waitTasks = TaskProgressHandler.getAllTaskName(k);
            tableDataList.add(new TableData(k, taskProgress, waitTasks));
        });
    }

    /**
     * 重置窗口位置大小
     */
    @FXML
    private void handleResetWindowPostButton() {
        HwndUtil.setWindowPost();
    }

    private void refreshData(TableData tableData) {
        TaskProgressHandler.setTableData(tableData);
    }

    @FXML
    private void showCurrentTasks(MouseEvent event) {
        String tasks = String.join("\n", TASK_SET);
        AppUtil.alter(event, "当前选中的任务", null, tasks.isEmpty() ? "没有选中任何任务" : tasks);
    }

    @FXML
    private void handleClearAllTasks(MouseEvent event) {
        log.debug("全部清空勾选的任务");
        checkBoxMap.forEach((k, v) -> {
            v.setSelected(false);
        });
    }
}
